<template>
  <div class="table_form_wrap">
    <el-row>
      <el-form
        :ref="refName"
        :model="formData"
        :inline="isInline"
        :disabled="allDisabled"
      >
        <el-row v-for="(rowNum, rowIndex) in totalRowNum" :key="rowIndex">
          <el-col
            v-for="(item, index) in formItemList.slice(
              rowIndex * colNumOfRow,
              rowNum * colNumOfRow
            )"
            :key="item.prop + index"
            :span="24 / colNumOfRow"
          >
            <el-form-item
              :prop="item.prop"
              :label="item.label"
              :label-width="item.width || formItemWidth"
            >
              <!-- 普通输入框 -->
              <template v-if="item.type === 'input'">
                <el-input
                  v-model.trim="formData[item.prop]"
                  :placeholder="item.placeholder || `请输入${item.label}`"
                  :disabled="item.disabled"
                  :clearable="item.clearable"
                />
              </template>
              <!-- 普通下拉框 -->
              <template v-else-if="item.type === 'select'">
                <el-select
                  v-model="formData[item.prop]"
                  style="width: 100%"
                  :multiple="item.multiple"
                  :filterable="item.filterable"
                  :filter-method="item.filterMethod"
                  :placeholder="item.placeholder || `请选择${item.label}`"
                  :disabled="item.disabled"
                  :clearable="item.clearable"
                  collapse-tags
                >
                  <template v-if="item.options && item.options.length">
                    <el-option
                      v-for="(option, key) in item.options"
                      :key="key"
                      :label="option.label"
                      :value="option.value"
                      :disabled="item.disabledValues && item.disabledValues.includes(option.value)"
                    />
                  </template>
                  <template v-else-if="item.dict">
                    <el-option
                      v-for="(option, key) in dictOptData[item.dict]"
                      :key="key"
                      :label="option.label"
                      :value="option.value"
                      :disabled="item.disabledValues && item.disabledValues.includes(option.value)"
                    />
                  </template>
                  <template v-else-if="item.sysDict">
                    <el-option
                      v-for="(option, key) in sysDictOptData[item.sysDict]"
                      :key="key"
                      :label="option.label"
                      :value="option.value"
                      :disabled="item.disabledValues && item.disabledValues.includes(option.value)"
                    />
                  </template>
                </el-select>
              </template>
              <!-- 用户中心用户信息 -->
              <template v-else-if="item.type === 'userSelect'">
                <UserSelect ref="userSelect" v-model="formData[item.prop]" />
              </template>
              <!-- 日期时间选择器 -->
              <template v-else-if="item.type === 'datePicker'">
                <!--
                  @datePickerType
                  默认不传为 daterange 日期选择器
                  datetimerange 为时间日期选择器
                  其余格式：year/month/date/dates/ week/datetime/monthrange
                -->
                <el-date-picker
                  v-model="formData[item.prop]"
                  :type="item.datePickerType || 'daterange'"
                  :title="dateTitle"
                  style="width: 100%"
                  :value-format="item.valueFormat || (item.datePickerType&&item.datePickerType==='datetimerange'?'yyyy-MM-dd HH:mm:ss':'yyyy-MM-dd')"
                  :range-separator="item.rangeSeparator || '-'"
                  :start-placeholder="item.startPlaceholder || '开始日期'"
                  :end-placeholder="item.endPlaceholder || '结束日期'"
                  :disabled="item.disabled"
                  :default-time="item.defaultTime"
                  @change="(data)=>{handleDateChange(data,item)}"
                />
              </template>
              <template v-else-if="item.type === 'timeRange'">
                <el-time-picker
                  is-range
                  v-model="formData[item.prop]"
                  value-format="HH:MM:SS"
                  range-separator="-"
                  start-placeholder="开始时间"
                  end-placeholder="结束时间"
                  :placeholder="item.placeholder || `请选择${item.label}`">
                </el-time-picker>
              </template>
              <!-- 数字选择 -->
              <template v-else-if="item.type === 'number'">
                <el-input-number
                  class="input-align-left"
                  v-model="formData[item.prop]"
                  :min="Number.isFinite(item.min) ? item.min :	-Infinity"
                  :max="Number.isFinite(item.max) ? item.max : Infinity"
                  :controls="item.controls || false"
                  :controls-position="item.controlsPosition || 'right'"
                  :precision="item.precision"
                  :placeholder="item.placeholder || `请输入${item.label}`"
                  :style="item.styles||{width: '100%'}"
                  :clearable="item.clearable"
                />
              </template>
              <template v-else-if="item.type === 'date'">
                <el-date-picker
                  v-model="formData[item.prop]"
                  value-format="yyyy-MM-dd"
                  type="date"
                  :placeholder="item.placeholder || `请选择${item.label}`">
                </el-date-picker>
              </template>
              <template v-else-if="item.type === 'year'">
                <el-date-picker
                  v-model="formData[item.prop]"
                  value-format="yyyy"
                  type="year"
                  :placeholder="item.placeholder || `请选择${item.label}`">
                </el-date-picker>
              </template>
              <template v-else-if="item.type === 'monthrange'">
                <el-date-picker
                  v-model="formData[item.prop]"
                  value-format="yyyy-MM"
                  type="monthrange"
                  range-separator="至"
                  start-placeholder="开始月份"
                  end-placeholder="结束月份"
                />
              </template>
              <template v-else-if="item.type === 'yearRange'">
                <el-col :span="11">
                  <el-form-item :prop="item.props[0]" class="inner-form-item">
                    <el-date-picker
                      v-model="formData[item.props[0]]"
                      type="year"
                      placeholder="开始年"
                      format="yyyy 年"
                      value-format="yyyy"
                    />
                  </el-form-item>
                </el-col>
                <el-col class="line" :span="2">-</el-col>
                <el-col :span="11">
                  <el-form-item :prop="item.props[1]" class="inner-form-item">
                    <el-date-picker
                      v-model="formData[item.props[1]]"
                      type="year"
                      placeholder="结束年"
                      format="yyyy 年"
                      value-format="yyyy"
                    />
                  </el-form-item>
                </el-col>
              </template>
              <!-- 数字范围选择 -->
              <template v-else-if="item.type === 'numberRange'">
                <el-col :span="11">
                  <el-input-number
                    :min="Number.isFinite(item.min) ? item.min :	-Infinity"
                    :max="Number.isFinite(formData[item.prop][1]) ? formData[item.prop][1] : Infinity"
                    :controls="item.controls || false"
                    :controls-position="item.controlsPosition || 'right'"
                    :precision="item.precision || 0"
                    :placeholder="item.startPlaceholder || `请输入最小值${item.label}`"
                    v-model="formData[item.prop][0]"
                    style="width: 100%;"
                  />
                </el-col>
                <el-col class="line" :span="2">~</el-col>
                <el-col :span="11">
                  <el-input-number
                    :min="Number.isFinite(formData[item.prop][0]) ? formData[item.prop][0] : -Infinity"
                    :max="Number.isFinite(item.max) ? item.max :	Infinity"
                    :controls="item.controls || false"
                    :controls-position="item.controlsPosition || 'right'"
                    :precision="item.precision || 0"
                    :placeholder="item.endPlaceholder || `请输入最大值${item.label}`"
                    v-model="formData[item.prop][1]"
                    style="width: 100%;"
                  />
                </el-col>
              </template>
              <!-- 远程搜索框 -->
              <template v-else-if="item.type === 'autocomplete'">
                <el-autocomplete
                  style="width: 100%"
                  v-model="formData[item.prop]"
                  :fetch-suggestions="item.fetchSuggestions"
                  :placeholder="item.placeholder || `请输入${item.label}`"
                  :disabled="item.disabled"
                  @select="item.handleSelect"
                />
              </template>
              <!-- 主营品类 -->
              <template v-else-if="item.type === 'categorySelect'">
                <CategorySelect ref="categorySelect" v-model="formData[item.prop]" />
              </template>
              <!-- 合作品牌 -->
              <template v-else-if="item.type === 'brandName'">
                <BrandNameSelect ref="brandName" v-model="formData[item.prop]" />
              </template>
              <!-- 管理区域 -->
              <template v-else-if="item.type === 'managementArea'">
                <ManagementAreaSelect ref="managementArea" v-model="formData[item.prop]" />
              </template>
              <!-- 归属中心 -->
              <template v-else-if="item.type === 'belongCenter'">
                <BelongCenterSelect ref="belongCenter" v-model="formData[item.prop]" />
              </template>
              <!-- 归属中心 -->
              <template v-else-if="item.type === 'saleArea'">
                <SaleAreaSelect ref="saleArea" v-model="formData[item.prop]" />
              </template>
              <!-- 选择供应商 -->
              <template v-else-if="item.type === 'supplierSelect'">
                <SupplierSelect ref="supplierSelect"
                  v-model="formData[item.prop]"
                  :invoice="item.invoice"
                  :placeholder="item.placeholder || `请${item.label}`"/>
              </template>
              <!-- 选择商品 -->
              <template v-else-if="item.type === 'productSelect'">
                <ProductSelect ref="productSelect"
                  v-model="formData[item.prop]"
                  :placeholder="item.placeholder || `请${item.label}`"/>
              </template>
              <!-- 选择部门 -->
              <template v-else-if="item.type === 'departmentSelect'">
                <DepartmentSelect ref="departmentSelect"
                  v-model="formData[item.prop]"
                  :placeholder="item.placeholder || `请输入${item.label}`"/>
              </template>
              <!-- 合作品牌 -->
              <template v-else-if="item.type === 'brandSelectOne'">
                <el-input
                  readonly
                  :value="brandDialog.data[item.prop]?brandDialog.data[item.prop].brandName:''"
                  :title="brandDialog.data[item.prop]?brandDialog.data[item.prop].brandName:''"
                  :disabled="item.disabled"
                  :placeholder="item.placeholder || `请选择${item.label}`"
                  @focus="brandDialog.prop=item.prop;brandDialog.visible = true"
                >
                  <el-button
                    slot="append"
                    icon="el-icon-search"
                    :disabled="item.disabled"
                    @click="brandDialog.prop=item.prop;brandDialog.visible = true"
                  ></el-button>
                </el-input>
              </template>
            </el-form-item>
          </el-col>
          <template v-if="formItemList.length < colNumOfRow * (rowIndex + 1) && !isBtnBarSingleRow">
            <el-row type="flex" :justify="actionPosition">
              <BtnRender :render="actionRender" />
              <slot name="extensionActions" />
            </el-row>
          </template>
        </el-row>
        <SelectBrandDialog
          title="选择合作品牌"
          :dialogVisible.sync="brandDialog.visible"
          :brandList="brandDialog.list"
          @handle-select="handleBrandSelect"
        />
      </el-form>
    </el-row>
    <el-row
      v-if="formItemList.length === totalRowNum * colNumOfRow || isBtnBarSingleRow"
      type="flex"
      :justify="actionPosition"
    >
      <slot name="action">
        <BtnRender :render="actionRender" />
      </slot>
      <slot name="extensionActions" />
    </el-row>
  </div>
</template>
<script>
import { mapGetters, mapState } from 'vuex';
import { getBtnsId } from '@/libs/btnsPermission';
import BtnRender from './BtnRender';
import UserSelect from '@/components/commodity/UserRemoteSelect'
import CategorySelect from '@/components/supplier/CategorySelect'
import BrandNameSelect from '@/components/supplier/BrandNameSelect'
import SelectBrandDialog from '@/pages/supplier/components/SelectBrandDialog'
import ManagementAreaSelect from '@/components/supplier/ManagementAreaSelect'
import BelongCenterSelect from '@/components/supplier/BelongCenterSelect'
import SupplierSelect from '@/components/supplier/SupplierSelect'
import ProductSelect from '@/components/supplier/ProductSelect'
import DepartmentSelect from '@/components/supplier/DepartmentRemoteSelect'
import SaleAreaSelect from '@/components/supplier/SaleAreaSelect'

export default {
  props: {
    formColumns: { // 表单item名集合
      type: Array,
      default () {
        return [];
      }
    },
    dataSource: { // 表单formData
      type: Object,
      default () {
        return {};
      }
    },
    formItemWidth: { // 表单item默认宽度
      type: String,
      default: '100px'
    },
    isInline: { // 表单是否开启inline模式
      type: Boolean,
      default: false
    },
    colNumOfRow: { // 表单每行col数量
      type: Number,
      default: 3
    },
    handleSearchForm: { // 查询方法
      type: Function
    },
    handleClearForm: { // 清空方法
      type: Function
    },
    searchBtnRender: { // 查询按钮（外部需要特殊渲染所用）
      type: Function
    },
    resetBtnRender: { // 清空按钮（外部需要特殊渲染所用）
      type: Function
    },
    searchBtnName: { // 查询按钮名称
      type: String,
      default: '查询'
    },
    resetBtnName: { // 清空按钮名称
      type: String,
      default: '清空'
    },
    isResetToQuery: { // 清空表单是否同时调用查询事件
      type: Boolean,
      default: false
    },
    refName: { // 表单ref名
      type: String,
      default: 'formData'
    },
    actionPosition: { // 表单操作按钮栏位置
      type: String,
      default: 'end'
    },
    allDisabled: { // 表单是否开启禁用
      type: Boolean,
      default: false
    },
    isScalingBtn: { // 是否展示收起或展开按钮
      type: Boolean,
      default: true
    },
    defaultExpandStatus: { // true为展开状态，按钮为收起；false为收起状态，按钮为展开
      type: Boolean,
      default: false
    },
    isBtnBarSingleRow: { // 按钮操作栏是否单独一行
      type: Boolean,
      default: false
    },
    hasQueryPermission: { // 是否需要查询按钮添加权限判断，默认添加
      type: Boolean,
      default: true
    }
  },
  components: {
    BtnRender,
    UserSelect,
    CategorySelect,
    BrandNameSelect,
    ManagementAreaSelect,
    BelongCenterSelect,
    SupplierSelect,
    ProductSelect,
    DepartmentSelect,
    SaleAreaSelect,
    SelectBrandDialog
  },
  data () {
    return {
      formData: this.dataSource,
      formItemList: this.formColumns,
      expandStatus: this.defaultExpandStatus,
      brandDialog: {
        visible: false,
        list: [],
        data: {},
        prop: '',
      },
    };
  },
  mounted () {
    if (!this.defaultExpandStatus) {
      this.handlePackUp();
    }
    // const { cooperativeBrandArr: brandArr = [] } = this.dataSource
    // if (brandArr && brandArr.length) {
    //   this.brandDialog.list = brandArr
    // }
  },
  computed: {
    ...mapState('supplier/dict', [
      'dictOptData',
      'sysDictOptData',
    ]),
    ...mapGetters('permissions/systemBtns', ['showBtn']),
    /* 总行数 */
    totalRowNum () {
      return Math.ceil(this.formItemList.length / this.colNumOfRow);
    },
    /* 日期选择器title */
    dateTitle () {
      let target = this.formItemList.find((item) => {
        return item.type === 'datePicker';
      });
      if (!target) {
        return '';
      }
      if (!this.formData[target.prop]) {
        return '';
      }
      if (target.datePickerType === 'date') {
        return '';
      }
      return this.formData[target.prop].join(' - ');
    },
  },
  watch: {
    formData: {
      handler (newVal) {},
      immediate: true,
      deep: true
    }
  },
  methods: {
    // 按钮控制栏有额外插槽按钮内容
    hasSlotByExtensionAction () {
      return Object.keys(this.$slots).length !== 0;
    },
    // 获取查询按钮栏类名
    getClassNameBySearchBtnBar () {
      return this.hasSlotByExtensionAction() ? 'table-action' : '';
    },
    /* 获取表单数据 */
    getFormDataFunc () {
      return this.formData;
    },
    /* 查询表单数据 */
    handleQueryForm (actionBtnName) {
      /* 如果没有name，就默认是查询按钮 */
      const curBtnId = getBtnsId(actionBtnName || this.searchBtnName);
      sessionStorage.setItem('buttonId', curBtnId);
      this.$emit('getFormData', this.formData);
      /* 如果有外部传入的查询方法，就进行调用 */
      if (this.handleSearchForm) {
        this.handleSearchForm(this.formData);
      }
    },
    handleFieldChanged (value, field) {
      this.$emit('change', { value, ...field })
      this.$emit('dataSource:update', this.formData)
    },
    handleBrandSelect (row) {
      console.log(this.brandDialog.prop)
      this.formData[this.brandDialog.prop] = row.uuid // parseInt(row.uuid,10)
      this.brandDialog.data[this.brandDialog.prop] = row
    },
    /* 清空表单数据 */
    handleResetForm () {
      if (this.brandDialog.prop) {
        this.brandDialog.data[this.brandDialog.prop] = ''
      }
      this.$refs[this.refName].resetFields();
      /* 如果有外部传入的清空方法，就进行调用 */
      if (this.handleClearForm) {
        this.handleClearForm();
      }
      /* 如果开启清空同时查询功能，就调用查询事件方法 */
      if (this.isResetToQuery) {
        this.handleQueryForm();
      }
      // 针对用户下拉单独处理
      this.$nextTick(() => {
        if (this.$refs.userSelect) {
          this.$refs.userSelect.forEach(item => {
            item.resetSelectVal()
          })
        }
        if (this.$refs.categorySelect) {
          this.$refs.categorySelect.forEach(item => {
            item.resetSelectVal()
          })
        }
        if (this.$refs.brandName) {
          this.$refs.brandName.forEach(item => {
            item.resetSelectVal()
          })
        }
        if (this.$refs.managementArea) {
          this.$refs.managementArea.forEach(item => {
            item.resetSelectVal()
          })
        }
        if (this.$refs.belongCenter) {
          this.$refs.belongCenter.forEach(item => {
            item.resetSelectVal()
          })
        }
        if (this.$refs.supplierSelect) {
          this.$refs.supplierSelect.forEach(item => {
            item.resetSelectVal()
          })
        }
        if (this.$refs.productSelect) {
          this.$refs.productSelect.forEach(item => {
            item.resetSelectVal()
          })
        }
        if (this.$refs.departmentSelect) {
          this.$refs.departmentSelect.forEach(item => {
            item.resetSelectVal()
          })
        }
      })
    },
    /* 收起表单事件 */
    handlePackUp () {
      this.expandStatus = false;
      this.formItemList = this.formColumns.reduce((value, item, index) => {
        if (index < this.colNumOfRow) {
          value.push(item);
        }
        return value;
      }, []);
    },
    /* 展开表单事件 */
    handleOpenUp () {
      this.expandStatus = true;
      this.formItemList = this.formColumns;
    },
    // 收起按钮
    packUpBtnFn () {
      return (<el-button
        type="text"
        icon="el-icon-arrow-up"
        onClick={() => { this.handlePackUp(); }}
      >收起</el-button>);
    },
    // 展开按钮
    openUpBtnFn () {
      return (<el-button
        type="text"
        icon="el-icon-arrow-down"
        onClick={() => { this.handleOpenUp(); }}
      >展开</el-button>);
    },
    // 查询按钮
    searchBtnFn () {
      // 如果开启权限，且没有查询按钮权限，就返回空标签
      if (this.hasQueryPermission && !this.showBtn(this.searchBtnName)) {
        return <div></div>;
      }
      // 如果有特殊渲染，返回特殊渲染的按钮
      if (this.searchBtnRender) {
        return this.searchBtnRender();
      }
      return (<el-button
        type="primary"
        onClick={() => { this.handleQueryForm(); }}
      >{this.searchBtnName}
      </el-button>);
    },
    // 清空按钮
    resetBtnFn () {
      // 如果有特殊渲染，返回特殊渲染的按钮
      if (this.resetBtnRender) {
        return this.resetBtnRender();
      }
      return (<el-button
        onClick={() => { this.handleResetForm(); }}
      >{this.resetBtnName}
      </el-button>);
    },
    actionRender (h) {
      const packUpBtn = this.packUpBtnFn();
      const openUpBtn = this.openUpBtnFn();
      const searchBtn = this.searchBtnFn();
      const resetBtn = this.resetBtnFn();
      let packOrOpenBtn = <div></div>;
      if (this.isScalingBtn) {
        packOrOpenBtn = this.expandStatus ? packUpBtn : openUpBtn;
      }
      return (
        <div class={this.getClassNameBySearchBtnBar()}>
          {packOrOpenBtn}
          {searchBtn}
          {resetBtn}
        </div>
      );
    },
    // 处理日期范围清空操作
    handleDateChange (data, item) {
      if (!data && (!item.datePickerType || item.datePickerType === 'daterange')) {
        this.$nextTick(() => {
          this.formData[item.prop] = []
        })
      }
    }
  }
};
</script>
<style lang="less" scoped>
/deep/ .el-range-input {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/deep/ .el-range-separator {
  display: flex;
  justify-content: center;
}
.table-action {
  margin-right: 10px;
}
.line {
 text-align: center;
}
</style>
<style lang="less">
.input-align-left input {
  text-align: left !important;
}
.inner-form-item {
  margin-bottom: 0 !important;
}
</style>
